package control;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import model.TwoWords;

public class TwoWordConstructor {

	private Map<String, Map<String,Integer>> twoWordsMap = new HashMap<String, Map<String,Integer>>();
	private Map<String, Map<String,Double>> nounNounMatrix = new HashMap<String, Map<String,Double>>();
	private Set<String> mainNounList = new HashSet<String>();
	private Map<String, Integer> nounTotalCntMap = new HashMap<String, Integer>();
	private List<String> wordList;

	public TwoWordConstructor() {
	}

	public void getNounCount(File dir) throws Exception {
		wordList = new ArrayList<String>();

		// We read each file in folders and get the nouns
		for (File inFile : dir.listFiles()) {

			//String fileN = inFile.getName().substring(0,inFile.getName().length() - 5);
			String line; 
			
			BufferedReader input = new BufferedReader(new InputStreamReader(new FileInputStream(inFile), "UTF-8"));
			
			// read characters
			while ((line = input.readLine()) != null)
			{
				int start = line.indexOf('[');
				int end = line.indexOf(']');
				if ((start > -1) && (end > -1) && (start < end)) {
					String bracketWord = line.substring((start + 1), end);

					if (bracketWord.equals("Noun")) {
						String noun = line.split("\\[")[0].split(" ")[line.split("\\[")[0].split(" ").length - 1];
						
						if (line.length() >= (end + 7))
						{	
							if (!line.substring((end + 3), (end + 7)).equals("Acro") &&
								!line.substring((end + 3),(end + 7)).equals("Prop") &&
								!line.substring((end + 3),(end + 7)).equals("Abbr"))
							{
								mainNounList.add(noun);
								wordList.add(noun);
								int count = nounTotalCntMap.containsKey(noun) ? nounTotalCntMap.get(noun): 0;
								nounTotalCntMap.put(noun, count+1);
							}
						}	
					} else if (bracketWord.equals("Punc") && !wordList.isEmpty() && wordList.size()>1 ) {
						addToMap();
						wordList.clear();
					}
				}
			}
			input.close();
		}
	}
	
	private void addToMap() {
		Map<String, Integer> wordMap;
		for(int i=0;i<=wordList.size()-1;i++) {
			String prevWord = wordList.get(i);

			if (twoWordsMap.containsKey(prevWord)) {
				wordMap = twoWordsMap.get(prevWord);
				for(int j=i+1;j<=wordList.size()-1;j++) {	
					String proWord = wordList.get(j);
					
					int count = twoWordsMap.get(prevWord).containsKey(proWord) ? twoWordsMap.get(prevWord).get(proWord) : 0;
					wordMap.put(proWord, count + 1);	
				} 
			} else {
				wordMap = new HashMap<String, Integer>();
				for(int j=i+1;j<=wordList.size()-1;j++) {	
					String proWord = wordList.get(j);
					wordMap.put(proWord,1);
				}	
			}
			if (!wordMap.isEmpty()) {
				twoWordsMap.put(prevWord, wordMap);
			}
		}
	}
	
	public void createNounNounMatrix() {
		Map<String, Double> wordMap;
		Iterator<String> setIterator1 = mainNounList.iterator();
	    while(setIterator1.hasNext()) {
	        String setElement1 = setIterator1.next();
	        Iterator<String> setIterator2 = mainNounList.iterator();
	        wordMap = new HashMap<String, Double>();
		    while(setIterator2.hasNext()) {
		        String setElement2 = setIterator2.next();
		        double ratio;
		        if (twoWordsMap.containsKey(setElement1) && twoWordsMap.get(setElement1).containsKey(setElement2)) {
			        	double dividend = (double) twoWordsMap.get(setElement1).get(setElement2);
			        	double divider = (double)nounTotalCntMap.get(setElement1);
			        	ratio = dividend / divider;
	        	System.out.println(twoWordsMap.get(setElement1).get(setElement2) + "--" + nounTotalCntMap.get(setElement1) +"--"+ratio);
	        	} else
	        		ratio = 0.0;
		        wordMap.put(setElement2, ratio);
		    }
		    nounNounMatrix.put(setElement1, wordMap);
		    System.out.println(nounNounMatrix.toString());
	    }    
	}

	public void writeNounNounMatrix(File outFile) throws Exception {
		BufferedWriter output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
		String line;
		Iterator mapIterator1 = nounNounMatrix.entrySet().iterator();
        while (mapIterator1.hasNext()) {
	        Map.Entry pairs1 = (Map.Entry)mapIterator1.next();
	        String prevWord = pairs1.getKey().toString();
	        Iterator mapIterator2 = nounNounMatrix.get(prevWord).entrySet().iterator();
	        line = prevWord + ";";
	        while (mapIterator2.hasNext()) {
	        	Map.Entry pairs2 = (Map.Entry)mapIterator2.next();
	        	String proWord = pairs2.getKey().toString();
	        	double ratio = (Double) pairs2.getValue();
	        	line = line + ratio + ";";
	        }
	        line = line.substring(0,line.length()-1);
	        output.append(line + "\n");    
        }
        output.close();
	}
}